﻿using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using HisoftSmart.Client.AutomationClient;
using System.Threading;
using HisoftSmart.Client.AutomationClient.UIAutomationServiceReference;
using HisoftSmart.Client.AutomationClient.Helpers;
using Microsoft.Phone.Controls;

namespace HisoftSmart.Client.AutomationClient.Actions
{
    public class ActionBase
    {
        public IConfiguration Configuration { get; set; }

        public AutomationClient AutomationClient { get; set; }

        public ResultBase Result { get; set; }

        public AutomationIdentifier AutomationIdentifier { get; set; }

        public int ID;

        public string Name;

        public string Params;

        public ActionBase(string name, string _params)
        {
            Name = name;
            Params = _params;
        }

        public void Do()
        {
            if (Configuration == null)
                throw new InvalidOperationException("Configuration must be set before Do() is called");

            try
            {
                DoImpl();
                //SendErrorResultIfNoOtherResultSent();
            }
            catch (Exception exception)
            {
                //SendExceptionFailedResult(exception);
                if (exception is ThreadAbortException)
                    throw;
            }
        }

        protected virtual void DoImpl()
        {
            // base class DoImpl() should never be called.
            throw new InvalidOperationException("DoImpl should never be called in CommandBase");
        }

        public void SendSuccessResult()
        {
            Send("Success");
        }

        public void SendFailedResult()
        {
            Send("Failed");
        }

        protected void SendNotFoundResult()
        {
            Send("NotFoundFailed");
        }

        protected void Send(string result)
        {
            this.Result = new ResultBase()
                    {
                        ActionBaseModel = new ActionBaseModel()
                        {
                            Name = this.Name,
                            ID = this.ID,
                            Params = this.Params,
                        },

                        Result = result
                    };
        }

        protected UIElement GetUIElement(bool sendNotFoundResultOnFail = true)
        {
            var element = AutomationElementFinder.FindElement(AutomationIdentifier);
            if (element == null)
            {
                if (sendNotFoundResultOnFail)
                    SendNotFoundResult();
                return null;
            }

            return element;
        }

        protected FrameworkElement GetFrameworkElement(bool sendNotFoundResultOnFail = true)
        {
            var element = AutomationElementFinder.FindElement(AutomationIdentifier) as FrameworkElement;
            if (element == null)
            {
                if (sendNotFoundResultOnFail)
                    SendNotFoundResult();
                return null;
            }

            return element;
        }

        protected FrameworkElement GetFrameworkElementParent<TParentType>(bool sendNotFoundResultOnFail = true)
            where TParentType : FrameworkElement
        {
            var element = AutomationElementFinder.FindElementsNearestParentOfType<TParentType>(AutomationIdentifier) as FrameworkElement;
            if (element == null)
            {
                if (sendNotFoundResultOnFail)
                    SendNotFoundResult();
                return null;
            }

            return element;
        }

        protected FrameworkElement GetApplicationRootVisual()
        {
            var rootVisual = (PhoneApplicationFrame)Application.Current.RootVisual;
            if (rootVisual == null)
                return null;

            return rootVisual;
        }
    }
}
